package org.dreamfly.dreamalarm;

import java.util.Locale;

import org.dreamfly.dreamalarm.bean.Alarm;
import org.dreamfly.dreamalarm.service.LocalService;
import org.dreamfly.dreamalarm.service.LocalService.LocalBinder;
import org.dreamfly.dreamalarm.service.WeiboService;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences.Editor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Vibrator;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.Toast;

import com.umeng.analytics.MobclickAgent;

public class AlertActivity extends LightScreenAndUnlockActivity
               implements DialogInterface.OnClickListener, OnInitListener,SensorEventListener{
	
	Alarm alarm;
	
	LocalService service;
	boolean mBound = false;
	
	//use for speech
	private TextToSpeech mTts;
	private static final int REQ_TTS_STATUS_CHECK = 0;
	private String speakSentence="";
	
	private boolean quitForBeginPlayer=false;
	
	private MediaPlayer mediaPlayer;
	private boolean mediaPlayerError=false;
	
	//定义sensor管理器
	private SensorManager mSensorManager;
	//上次晃动  当前时间 
    private long lastShakeTime=0;
    private long currentTime=0;
    // 记数器
 	private int counter = 0;
	
    //震动 
  	private Vibrator vibrator;
  	
  	public static final String weibo_service_key="back_weiboservice_on";  //是否已经开启了微博线程
  	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		MobclickAgent.onError(this);
		alarm=(Alarm)this.getIntent().getSerializableExtra(Constants.KEY_BETWEEN_ACTIVITY_ALARM);
		
		initService();
		initSensorManager();
		initVibrator();
		
		if(alarm.getType()==Alarm.TYPE_GETUP && !alarm.isSilence()){
			initMediaplayer();   //与checkTTS不能更换顺序
			checkTTS();
		}
		addPhoneListener();
		
		//下面两项顺序不能修改
		initSpeakSentence();
	    initFrame();
	    
	    changeWorkTime();
	}
	
	/**
	 * 初始化操作闹钟的服务
	 */
	private void initService(){
		Intent intent = new Intent(AlertActivity.this,LocalService.class);
		bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
	}
	
	/**
	 * 检查TTS数据是否已经安装并且可用，进对支持英语的系统语言使用
	 */
	private void checkTTS(){
		if(getLocaleLanguage().substring(0, 2).equals("en")){
			Intent checkIntent = new Intent();
	        checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
	        startActivityForResult(checkIntent, REQ_TTS_STATUS_CHECK);
		}
	}
	
	private String getLocaleLanguage() {  
        Locale l = Locale.getDefault();  
        return String.format("%s-%s", l.getLanguage(), l.getCountry());  
    }  
	
	/**
	 * 初始化传感器服务
	 */
	private void initSensorManager(){
		//获取传感器管理服务 
	    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
	}
	
	/**
	 * 初始化震动需要的参数
	 */
	private void initVibrator(){
	    vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE);
	    long[] pattern = {800, 200, 800, 200};
	    vibrator.vibrate(pattern, 2);  
	}
	
	/**
	 * 初始化读出的内容
	 */
	private void initSpeakSentence(){
		if(alarm.getType()==Alarm.TYPE_GETUP){
	    	speakSentence=this.getResources().getString(R.string.alertactivity_speak_proffix)+
	    			" "+(alarm.getWorkTimeDate().getTimeInMillis()-System.currentTimeMillis())/1000/60+
	    			" "+this.getResources().getString(R.string.alertactivity_speak_suffix);
	    }
	}
	
	/**
	 * 初始化界面及各个部件
	 */
	private void initFrame(){
		Builder builder=new AlertDialog.Builder(AlertActivity.this);  
		builder.setCancelable(false);
		builder.setTitle(this.getResources().getString(R.string.alertactivity_dialog_title));  
        builder.setMessage(buildMessageText(alarm));
        
        boolean haveButton=false;   //判断时候有关闭闹钟button，来确定延迟闹钟的设置方式
        
        //end button
        if(alarm.getEndType()==Alarm.Handle_BUTTON){
        	builder.setPositiveButton(
        			this.getResources().getString(R.string.alertactivity_dialog_button_endclock),this);
        	haveButton=true;
        }
        
        //ring later button
        if(alarm.getReringInterval()!=0){
        	if(haveButton){
        		builder.setNegativeButton(this.getResources().getString(R.string.alertactivity_dialog_button_ringlater), 
        				this);
        	}else{
        		builder.setPositiveButton(this.getResources().getString(R.string.alertactivity_dialog_button_ringlater), 
        				this);
        	}
        }
        
        builder.show();   
	}
	
	/**
	 * 修改微博发布服务的工作时间，改为最近的一次工作时间，提高用户体验
	 */
	private void changeWorkTime(){
		 if(alarm.getType()==Alarm.TYPE_GETUP){
			if(!getSharedPreferences(DreamAlarmActivity.SHAREPREFERENCE_DATA, 0).getBoolean(weibo_service_key, false)){	
				//首先检查网络
		    	ConnectivityManager manager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);    
		        NetworkInfo networkinfo = manager.getActiveNetworkInfo();    
		        if (networkinfo != null && !networkinfo.isAvailable()) {    
		            Intent i = new Intent("org.dreamfly.dreamfly.weiboservice");
					i.putExtra("work_time", alarm.getWorkTimeDate().getTimeInMillis());
					startService(i);
						
					Editor sharedata = getSharedPreferences(DreamAlarmActivity.SHAREPREFERENCE_DATA, 0)
							.edit();
					sharedata.putBoolean(weibo_service_key, true);
					sharedata.commit();
				}   
			}else{
		    	WeiboService.changeWorkTime(alarm.getWorkTimeDate().getTimeInMillis());
		    }
		 }
	}
	
	/**
	 * 设置对话框中要显示的文字的内容
	 * @param alarm
	 * @return
	 */
	private String buildMessageText(Alarm alarm){
		String message=(alarm.getTag().equals(""))?"":alarm.getTag()+'\n';
		String temp=speakSentence;
		if(!temp.trim().equals("")){
			message+=speakSentence+'\n';
		}
		if(alarm.getEndType()==Alarm.Handle_SHOCK){
			message+=this.getResources().getString(R.string.alertactivity_dialog_message_shock);
			message+=" ";
			message+=this.getResources().getString(R.string.alertactivity_dialog_message_toendclock);
		}
		
		if(alarm.getType()==Alarm.TYPE_GETUP){
			message+=this.getResources().getString(R.string.alertactivity_dialog_message_info_havegetup_useweibo);
		}
		return message;
	}
	
	/**
	 * 关闭此闹钟，并关闭相应资源，跳转页面
	 */
	private void endAlarmHandle(){
		quitForBeginPlayer=true;
		
		releaseTTS();
		releaseMediaPlayer();
		
		vibrator.cancel();
		service.endAlarm(alarm);
     	AlertActivity.this.finish();
	}
	
	/**
	 * 释放TTS资源
	 */
	private void releaseTTS(){
		if(mTts!=null){
			mTts.stop();
			mTts.shutdown();
			mTts=null;
		}
	}
	
	/**
	 * 释放mediaplayer资源
	 */
	private void releaseMediaPlayer(){
		if(mediaPlayer!=null  && !mediaPlayerError){
			if(mediaPlayer.isPlaying())
				mediaPlayer.stop();
			mediaPlayer.release();
			mediaPlayer=null;
		}
	}
	
    private ServiceConnection mConnection = new ServiceConnection() {  
		
		public void onServiceConnected(ComponentName name, IBinder iBinder) {
			// TODO Auto-generated method stub
			LocalBinder binder = (LocalBinder) iBinder;
			service = binder.getService();
			mBound = true;
		}

		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			service = null;
			mBound = false;
		}  
    };   
	
    //--------------------------------------------------------------
  	// DialogInterface.OnClickListener,SensorEventListener
    // 实现对话框中的button处理事件，摇动手机事件处理
    
	@Override
	public void onClick(DialogInterface dialog, int which) {
		// TODO Auto-generated method stub
		if(which==DialogInterface.BUTTON_POSITIVE && alarm.getEndType()==Alarm.Handle_BUTTON){
			endAlarmHandle();
		}else{
			service.delayRinging(alarm);
			this.finish();
		}
	}
	
	@Override 
	public boolean onKeyDown(int keyCode, KeyEvent event) { 
	    // BACK key    
	    if (keyCode == KeyEvent.KEYCODE_BACK) {
	    	return true;
	    }
	    return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
		//当传感器精度改变时回调该方法，Do nothing.
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		// TODO Auto-generated method stub
		
		//当设置为摇动手机关闭闹钟时，摇动手机关闭闹钟
		if(alarm.getEndType()==Alarm.Handle_SHOCK){
			int sensorType = event.sensor.getType();
			 
			//values[0]:X轴，values[0]：Y轴，values[0]：Z轴
			float[] values = event.values;
			 
			if(sensorType == Sensor.TYPE_ACCELEROMETER){
				/*因为一般正常情况下，任意轴数值最大就在9.8~10之间，只有在你突然摇动手机
				 *的时候，瞬时加速度才会突然增大或减少。
				 *所以，经过实际测试，只需监听任一轴的加速度大于14的时候，改变你需要的设置
				 *就OK了~~~
				 */
				currentTime=System.currentTimeMillis();
			    if((Math.abs(values[0])>14||Math.abs(values[1])>14||Math.abs(values[2])>14)){		  
			    	// 摇动手机后，设置button上显示的字为空
					if (currentTime - lastShakeTime > 200) {
						if (counter == 3) {
							//执行关闹钟
				    		endAlarmHandle();
							counter = 0;
						} else {
							counter++;
						}
					}
				}
			    
				lastShakeTime=currentTime; 
			} 
		}
	}

	//--------------------------------------------------------------
	// 语音和音乐
	
	private void initMediaplayer(){
		if(alarm.getType()==Alarm.TYPE_GETUP && !alarm.isSilence()){
	    	mediaPlayer=MediaPlayer.create(AlertActivity.this, Uri.parse(alarm.getRingSource()));
	    	
	    	if(mediaPlayer!=null){
	    		mediaPlayer.setOnErrorListener(new android.media.MediaPlayer.OnErrorListener(){

					@Override
					public boolean onError(MediaPlayer mp, int what, int extra) {
						// TODO Auto-generated method stub
						mediaPlayerError=true;
						Log.d("MediaPlayerError", "what:"+what+",extra:"+extra);
						return false;
					}
	    			
	    		});
	    		mediaPlayer.setLooping(true);
		    	mediaPlayer.start();
	    	}
	    }
	}
	
	//实现TTS初始化接口
	@Override
	public void onInit(int status) {
		// TODO Auto-generated method stub	
		//TTS Engine初始化完成
		if(status == TextToSpeech.SUCCESS){
			int result = mTts.setLanguage(Locale.US);
			//设置发音语言
			if(result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED){
			    //判断语言是否可用
				mTts.shutdown();
				mTts=null;
			}
		}
		
		if(!quitForBeginPlayer){
			if(mTts!=null && alarm.getType()==Alarm.TYPE_GETUP){
				if(mediaPlayer!=null && mediaPlayer.isPlaying())
					releaseMediaPlayer();
		    	mTts.speak(speakSentence, TextToSpeech.QUEUE_ADD, null);
		    	new Thread(new MyThread()).start();
		    }
		}
	}
	
	/**
	 * 新线程，用于保证语音播报完之后才响起音乐
	 * @author Jason_wbw
	 *
	 */
	class MyThread implements Runnable {
        public void run() {
        	while(mTts.isSpeaking()){}
        	if(!quitForBeginPlayer)
				initMediaplayer();
        }
    }
	
	protected  void onActivityResult(int requestCode, int resultCode, Intent data) {
		//检测TTS安装情况的反馈信息
		if(requestCode == REQ_TTS_STATUS_CHECK){
			switch (resultCode) {
			case TextToSpeech.Engine.CHECK_VOICE_DATA_BAD_DATA:
				//需要的语音数据已损坏
			case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_DATA:
				//缺少需要语言的语音数据
			case TextToSpeech.Engine.CHECK_VOICE_DATA_MISSING_VOLUME:
				//缺少需要语言的发音数据
				//这三种情况都表明数据有错,重新下载安装需要的数据
				Log.d(Constants.LOGTAG, "Need language stuff:"+resultCode);
			case TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL:
				//检查失败
				Toast.makeText(this, R.string.alertactivity_toast_tts, Toast.LENGTH_SHORT).show();
			case TextToSpeech.Engine.CHECK_VOICE_DATA_PASS:
				//这个返回结果表明TTS Engine可以用			
				mTts = new TextToSpeech(this, this);
				Log.d(Constants.LOGTAG, "TTS Engine is installed!");
				break;
			default:
				Log.d(Constants.LOGTAG, "Got a failure. TTS apparently not available");
				break;
			}
		}else{
			//其他Intent返回的结果
		}
	}
	
	//--------------------------------------------------------------
	// activity各种状态
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		vibrator.cancel();
		releaseTTS();
		releaseMediaPlayer();
		
		mSensorManager.unregisterListener(this);
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}
	
	@Override 
	protected void onResume(){ 
		super.onResume(); 
		//加速度传感器 
		mSensorManager.registerListener(this, 
				mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
		        //还有SENSOR_DELAY_UI、SENSOR_DELAY_FASTEST、SENSOR_DELAY_GAME等， 
		        //根据不同应用，需要的反应速率不同，具体根据实际情况设定 
		        SensorManager.SENSOR_DELAY_NORMAL); 
	}
	
	@Override
	protected void onStop() {
	    // TODO Auto-generated method stub
		super.onStop();
		if (mBound) {
			unbindService(mConnection);
			mBound = false;
		}
		mSensorManager.unregisterListener(this);
	}
	
	//--------------------------------------------------------------
	// 监听来电状态
	
	private void addPhoneListener(){
		//添加自己实现的PhoneStateListener
		ExPhoneCallListener myPhoneCallListener = new ExPhoneCallListener();
        
        //取得电话服务 
        TelephonyManager tm =(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        
        //注册电话通信Listener
        tm.listen(myPhoneCallListener,
        		PhoneStateListener.LISTEN_CALL_STATE);
	}
	
	boolean phoneCall=false;
	
	/**
	 * 内部class继承PhoneStateListener 
	 * */
	public class ExPhoneCallListener extends PhoneStateListener
	{
	    /* 重写onCallStateChanged
	    当状态改变时改变myTextView1的文字及颜色 */
	    public void onCallStateChanged(int state, String incomingNumber)
	    {
	      switch (state)
	      {
	        /* 无任何状态时 */
	        case TelephonyManager.CALL_STATE_IDLE:
	        	if(phoneCall){
	        		phoneCall=false;
	        	}
	        	break;
	        /* 电话进来时 */
	        case TelephonyManager.CALL_STATE_RINGING:
	        	phoneCall=true;
	        	vibrator.cancel();
	        	releaseTTS();
	    		releaseMediaPlayer();
	        	break;
	        default:
	        	break;
	      }
	      super.onCallStateChanged(state, incomingNumber);
	    }
	}
}
